#include "verticesPanel.h"

#include <iostream>

VerticesPanel::VerticesPanel(QWidget* _parent, Scene *_s) : QWidget(_parent), scene(_s){
//    setFixedHeight(230);
    setMaximumHeight(230);
    type = 0;
    n = 10;
    rx = ry = rz = 1.0;
    qx = qy = qz = 1.0;
    x = y = z = 0.0;
    srand ( time(NULL) );

    QComboBox *typeComboBox = new QComboBox(this);
    typeComboBox->addItem(QString::fromUtf8("Elipsoide"));
    typeComboBox->addItem(QString::fromUtf8("Quadrilátero"));
    typeComboBox->addItem(QString::fromUtf8("Ponto específico"));
    connect(typeComboBox, SIGNAL(activated(int)), this, SLOT(changeType(int)));

    nLabel = new QLabel(QString::fromUtf8("Número de vertices:"));
    nSpinBox = new QSpinBox();
    nSpinBox->setRange(1, 500);
    nSpinBox->setSingleStep(5);
    nSpinBox->setValue(n);
    connect(nSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeN(int)));

    rxLabel = new QLabel(tr("Raio em x:"));
    rxSpinBox = new QSpinBox();
    rxSpinBox->setRange(1, 100);
    rxSpinBox->setSingleStep(1);
    rxSpinBox->setValue(rx);
    connect(rxSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeRX(int)));

    ryLabel = new QLabel(tr("Raio em y:"));
    rySpinBox = new QSpinBox();
    rySpinBox->setRange(1, 100);
    rySpinBox->setSingleStep(1);
    rySpinBox->setValue(ry);
    connect(rySpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeRY(int)));

    rzLabel = new QLabel(tr("Raio em z:"));
    rzSpinBox = new QSpinBox();
    rzSpinBox->setRange(1, 100);
    rzSpinBox->setSingleStep(1);
    rzSpinBox->setValue(rz);
    connect(rzSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeRZ(int)));

    qxLabel = new QLabel(tr("Raio em x:"));
    qxLabel->hide();
    qxSpinBox = new QSpinBox();
    qxSpinBox->setRange(1, 100);
    qxSpinBox->setSingleStep(1);
    qxSpinBox->setValue(qx);
    qxSpinBox->hide();
    connect(qxSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeQX(int)));

    qyLabel = new QLabel(tr("Raio em y:"));
    qyLabel->hide();
    qySpinBox = new QSpinBox();
    qySpinBox->setRange(1, 100);
    qySpinBox->setSingleStep(1);
    qySpinBox->setValue(qy);
    qySpinBox->hide();
    connect(qySpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeQY(int)));

    qzLabel = new QLabel(tr("Raio em z:"));
    qzLabel->hide();
    qzSpinBox = new QSpinBox();
    qzSpinBox->setRange(1, 100);
    qzSpinBox->setSingleStep(1);
    qzSpinBox->setValue(qz);
    qzSpinBox->hide();
    connect(qzSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeQZ(int)));

    xLabel = new QLabel(tr("Coordenada x:"));
    xLabel->hide();
    xDoubleSpinBox = new QDoubleSpinBox();
    xDoubleSpinBox->setRange(-100.0, 100.0);
    xDoubleSpinBox->setSingleStep(1.0);
    xDoubleSpinBox->setValue(x);
    xDoubleSpinBox->hide();
    connect(xDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeX(double)));

    yLabel = new QLabel(tr("Coordenada y:"));
    yLabel->hide();
    yDoubleSpinBox = new QDoubleSpinBox();
    yDoubleSpinBox->setRange(-100.0, 100.0);
    yDoubleSpinBox->setSingleStep(1.0);
    yDoubleSpinBox->setValue(y);
    yDoubleSpinBox->hide();
    connect(yDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeY(double)));

    zLabel = new QLabel(tr("Coordenada z:"));
    zLabel->hide();
    zDoubleSpinBox = new QDoubleSpinBox();
    zDoubleSpinBox->setRange(-100.0, 100.0);
    zDoubleSpinBox->setSingleStep(1.0);
    zDoubleSpinBox->setValue(z);
    zDoubleSpinBox->hide();
    connect(zDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeZ(double)));

	QPushButton *addButton = new QPushButton(tr("Adiciona"), this);
	connect(addButton, SIGNAL(clicked(bool)), this, SLOT(add(void)));

    QHBoxLayout *nLayout = new QHBoxLayout;
	nLayout->addWidget(nLabel);
	nLayout->addWidget(nSpinBox);

    QFormLayout *rxyzLayout = new QFormLayout;
    rxyzLayout->addRow(rxLabel, rxSpinBox);
    rxyzLayout->addRow(ryLabel, rySpinBox);
    rxyzLayout->addRow(rzLabel, rzSpinBox);
//	rxyzLayout->addWidget(rxLabel);
//	rxyzLayout->addWidget(rxSpinBox);
//	rxyzLayout->addStretch(100);
//	rxyzLayout->addWidget(ryLabel);
//	rxyzLayout->addWidget(rySpinBox);
//	rxyzLayout->addStretch(100);
//	rxyzLayout->addWidget(rzLabel);
//	rxyzLayout->addWidget(rzSpinBox);
//	rxyzLayout->addStretch(100);

    QFormLayout *qxyzLayout = new QFormLayout;
    qxyzLayout->addRow(qxLabel, qxSpinBox);
    qxyzLayout->addRow(qyLabel, qySpinBox);
    qxyzLayout->addRow(qzLabel, qzSpinBox);
//	qxyzLayout->addWidget(qxLabel);
//	qxyzLayout->addWidget(qxSpinBox);
//	qxyzLayout->addStretch(100);
//	qxyzLayout->addWidget(qyLabel);
//	qxyzLayout->addWidget(qySpinBox);
//	qxyzLayout->addStretch(100);
//	qxyzLayout->addWidget(qzLabel);
//	qxyzLayout->addWidget(qzSpinBox);
//	qxyzLayout->addStretch(100);

    QFormLayout *xyzLayout = new QFormLayout;
    xyzLayout->addRow(xLabel, xDoubleSpinBox);
    xyzLayout->addRow(yLabel, yDoubleSpinBox);
    xyzLayout->addRow(zLabel, zDoubleSpinBox);
//	xyzLayout->addWidget(xLabel);
//	xyzLayout->addWidget(xDoubleSpinBox);
//	xyzLayout->addStretch(100);
//	xyzLayout->addWidget(yLabel);
//	xyzLayout->addWidget(yDoubleSpinBox);
//	xyzLayout->addStretch(100);
//	xyzLayout->addWidget(zLabel);
//	xyzLayout->addWidget(zDoubleSpinBox);
//	xyzLayout->addStretch(100);

    QVBoxLayout *layout = new QVBoxLayout;
	layout->addWidget(typeComboBox);
	layout->addLayout(nLayout);
	layout->addStretch(0);
	layout->addLayout(rxyzLayout);
	layout->addStretch(0);
	layout->addLayout(qxyzLayout);
	layout->addStretch(0);
	layout->addLayout(xyzLayout);
	layout->addStretch(0);
	layout->addWidget(addButton);

    setLayout(layout);
}

VerticesPanel::~VerticesPanel(){
}

void VerticesPanel::setScene(Scene *_s){
    scene = _s;
}

void VerticesPanel::changeType(int _index){
    type = _index;

    switch(type){
        case 0: //Elipsoide
            nSpinBox->show();
            nLabel->show();

            rxSpinBox->show();
            rySpinBox->show();
            rzSpinBox->show();
            rxLabel->show();
            ryLabel->show();
            rzLabel->show();

            qxSpinBox->hide();
            qySpinBox->hide();
            qzSpinBox->hide();
            qxLabel->hide();
            qyLabel->hide();
            qzLabel->hide();

            xDoubleSpinBox->hide();
            yDoubleSpinBox->hide();
            zDoubleSpinBox->hide();
            xLabel->hide();
            yLabel->hide();
            zLabel->hide();
            break;
        case 1: //quadrilatero
            nSpinBox->show();
            nLabel->show();

            rxSpinBox->hide();
            rySpinBox->hide();
            rzSpinBox->hide();
            rxLabel->hide();
            ryLabel->hide();
            rzLabel->hide();

            qxSpinBox->show();
            qySpinBox->show();
            qzSpinBox->show();
            qxLabel->show();
            qyLabel->show();
            qzLabel->show();

            xDoubleSpinBox->hide();
            yDoubleSpinBox->hide();
            zDoubleSpinBox->hide();
            xLabel->hide();
            yLabel->hide();
            zLabel->hide();
            break;
        case 2: //quadrilatero
            nSpinBox->hide();
            nLabel->hide();

            rxSpinBox->hide();
            rySpinBox->hide();
            rzSpinBox->hide();
            rxLabel->hide();
            ryLabel->hide();
            rzLabel->hide();

            qxSpinBox->hide();
            qySpinBox->hide();
            qzSpinBox->hide();
            qxLabel->hide();
            qyLabel->hide();
            qzLabel->hide();

            xDoubleSpinBox->show();
            yDoubleSpinBox->show();
            zDoubleSpinBox->show();
            xLabel->show();
            yLabel->show();
            zLabel->show();
            break;

    }
}

void VerticesPanel::changeN(int _n){
    n = _n;
}

void VerticesPanel::changeRX(int _x){
    rx = _x;
}

void VerticesPanel::changeRY(int _y){
    ry = _y;
}

void VerticesPanel::changeRZ(int _z){
    rz = _z;
}

void VerticesPanel::changeQX(int _x){
    qx = _x;
}

void VerticesPanel::changeQY(int _y){
    qy = _y;
}

void VerticesPanel::changeQZ(int _z){
    qz = _z;
}

void VerticesPanel::changeX(double _x){
    x = _x;
}

void VerticesPanel::changeY(double _y){
    y = _y;
}

void VerticesPanel::changeZ(double _z){
    z = _z;
}

void VerticesPanel::add(){
    Object *obj = NULL;
    std::vector<Object *> selectObjects = scene->getSelectedObjects();
    if(selectObjects.empty()){
        obj = new Object(scene->nextObjectsID());
        scene->addObject(obj);
        add(obj);
        return;
    }

    for(unsigned int i = 0; i < selectObjects.size(); i++){
        obj = selectObjects.at(i);
        add(obj);
    }
}

void VerticesPanel::add(Object * _obj){
    _obj->setConvexHull(false);
    _obj->setTetrahedrons(false);
    double randX, randY, randZ;
    int i = 0;
    switch(type){
        case 0:{ //pontos aleatórios em uma esfera
            do {
                randX = rand()%(2000*rx)/1000.0 - rx;
                randY = rand()%(2000*ry)/1000.0 - ry;
                randZ = rand()%(2000*rz)/1000.0 - rz;

                if (((randX * randX)/(rx*rx)) + ((randY * randY)/(ry*ry)) + ((randZ * randZ)/(rz*rz)) <= 1){
                    _obj->addVertex(new Vertex(scene->nextVerticesID(), Point(randX, randY, randZ)));
                    i++;
                }
            }while(i < n);
            break;
        }
        case 1:{ //pontos aleatórios em um quadrado
            do {
                randX = rand()%(2000*qx)/1000.0 - qx;
                randY = rand()%(2000*qy)/1000.0 - qy;
                randZ = rand()%(2000*qz)/1000.0 - qz;

                _obj->addVertex(new Vertex(scene->nextVerticesID(), Point(randX, randY, randZ)));
                i++;
            }while(i < n);
            break;
        }
        case 2:{ //criando um ponto especifico
            _obj->addVertex(new Vertex(scene->nextVerticesID(), Point(x, y, z)));
        }
    }

    emit done(_obj);
}
